package framework.proxy;

import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * 基于动态代理实现，用于将对象属性映射到字典
 * 通过拦截get/set方法调用，将属性存取操作转发到内部Map存储
 * 注意：不处理类中 boolean 类型, 而应使用包装类型 Boolean
 */
public class MapPropertyProxy implements MethodInterceptor {
    private final Map<String, Object> map = new HashMap<>();

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        String name = method.getName();
        if (name.startsWith("get") && args.length == 0) {
            String fieldName = name.substring(3);
            fieldName = Character.toLowerCase(fieldName.charAt(0)) + fieldName.substring(1);
            return map.get(fieldName);
        } else if (name.startsWith("set") && args.length == 1) {
            String fieldName = name.substring(3);
            fieldName = Character.toLowerCase(fieldName.charAt(0)) + fieldName.substring(1);
            map.put(fieldName, args[0]);
            return null;
        } else if (name.equals("properties")) {
            return map;
        } else if (name.startsWith("is") && method.getReturnType() == boolean.class) {
            throw new RuntimeException(name + " not supported, not allow use boolean type or modify it to Boolean type");
        }
        // other
        return proxy.invokeSuper(obj, args);
    }
}
